"""
解码工具类，支持多种主流解密方式
"""

import base64
import hashlib
from typing import Union

try:
    from Crypto.Cipher import DES3, AES
    from Crypto.Util.Padding import pad, unpad
    from Crypto.PublicKey import RSA
    from Crypto.Cipher import PKCS1_OAEP
    CRYPTO_AVAILABLE = True
except ImportError:
    CRYPTO_AVAILABLE = False
    print("警告: pycryptodome库未安装，部分解密功能将不可用。请运行: pip install pycryptodome")


class Decoder:
    """
    解码器类，支持多种解密方式
    """

    @staticmethod
    def base64_decode(encoded_text: str) -> str:
        """
        Base64解码

        :param encoded_text: 待解码的base64字符串
        :return: 解码后的字符串
        """
        return base64.b64decode(encoded_text.encode('utf-8')).decode('utf-8')

    @staticmethod
    def des3_decrypt(encrypted_text: str, key: str) -> str:
        """
        3DES解密

        :param encrypted_text: 待解密的base64编码字符串
        :param key: 密钥（长度必须为24字节，或自动填充）
        :return: 解密后的字符串
        """
        if not CRYPTO_AVAILABLE:
            raise Exception("解密库不可用，请安装pycryptodome")

        # 调整密钥长度为24字节
        if len(key) < 24:
            key = key.ljust(24, '\0')
        elif len(key) > 24:
            key = key[:24]

        # base64解码
        encrypted_data = base64.b64decode(encrypted_text.encode('utf-8'))

        # 创建3DES对象
        cipher = DES3.new(key.encode('utf-8'), DES3.MODE_ECB)
        
        # 解密
        decrypted = cipher.decrypt(encrypted_data)
        
        # 去除填充
        unpadded = unpad(decrypted, DES3.block_size)
        
        # 返回解密后的字符串
        return unpadded.decode('utf-8')

    @staticmethod
    def aes_decrypt(encrypted_text: str, key: str) -> str:
        """
        AES解密

        :param encrypted_text: 待解密的base64编码字符串
        :param key: 密钥（长度必须为16、24或32字节）
        :return: 解密后的字符串
        """
        if not CRYPTO_AVAILABLE:
            raise Exception("解密库不可用，请安装pycryptodome")

        # 调整密钥长度
        key_bytes = len(key.encode('utf-8'))
        if key_bytes < 16:
            key = key.ljust(16, '\0')
        elif key_bytes > 32:
            key = key[:32]
        elif 16 < key_bytes < 24:
            key = key[:16]
        elif 24 < key_bytes < 32:
            key = key[:24]

        # 转换为字节
        key = key.encode('utf-8')
        
        # base64解码
        encrypted_data = base64.b64decode(encrypted_text.encode('utf-8'))

        # 创建AES对象
        cipher = AES.new(key, AES.MODE_ECB)
        
        # 解密
        decrypted = cipher.decrypt(encrypted_data)
        
        # 去除填充
        unpadded = unpad(decrypted, AES.block_size)
        
        # 返回解密后的字符串
        return unpadded.decode('utf-8')

    @staticmethod
    def rsa_decrypt(encrypted_text: str, private_key: Union[str, bytes]) -> str:
        """
        RSA解密

        :param encrypted_text: 待解密的base64编码字符串
        :param private_key: 私钥路径或私钥内容
        :return: 解密后的字符串
        """
        if not CRYPTO_AVAILABLE:
            raise Exception("解密库不可用，请安装pycryptodome")

        # 判断是路径还是密钥内容
        if private_key.startswith("-----BEGIN PRIVATE KEY-----") or private_key.startswith("-----BEGIN RSA PRIVATE KEY-----"):
            # 是密钥内容
            rsa_key = RSA.import_key(private_key)
        else:
            # 是路径
            with open(private_key, 'r') as f:
                rsa_key = RSA.import_key(f.read())

        cipher = PKCS1_OAEP.new(rsa_key)
        encrypted_data = base64.b64decode(encrypted_text.encode('utf-8'))
        decrypted = cipher.decrypt(encrypted_data)
        return decrypted.decode('utf-8')